/*
 *   AS IS License
 * ==Naive Coders==
 */
package org.naive.metawatch.converter.parser.cap;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.LinkedList;
import java.util.List;
import org.naive.metawatch.converter.parser.ParseContext;
import org.naive.metawatch.converter.parser.Parseable;

/**
 *
 * @author gbu.000
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ParsedArrayTillBlockEnds {
    
    Class<? extends Parseable> itemClass();

    public class FieldParser {

        public static Object parse(ParsedArrayTillBlockEnds p, ParseContext x, Field f) throws Exception {
            Class<?> componentType = f.getType().getComponentType();
            List<Object> parsedItems = new LinkedList<>();
            while (!((CapParseContext)x).isAtBlockBoundary()) {
                final Parseable item = p.itemClass().newInstance();
                item.parse(x);
                parsedItems.add(item);
            }
            // no simple way of transforming 
            // list into array with runtime specified element type... sigh
            final Object array = Array.newInstance(componentType, parsedItems.size());
            int i =0;
            for (Object item: parsedItems) {
                Array.set(array, i++, item);
            }
            return array;
        }
    }
}
